using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AhpilyServer;
using AhpilyServers;
using GameServer.Cache;
using GameServer.Cache.Match;
using GameServer.Model;
using Protocol.Code;
using Protocol.Dto;

namespace GameServer.Logic
{
    public delegate void StartFight(List<int> uidList);

    public class MatchHandler : IHeadler
    {
        public StartFight startFight;

        private MatchCache matchCache1 = Caches.Match1;

        private UserCache userCache = Caches.User;

        public void OnDisconnect(ClientPeer client)
        {
            if (!userCache.IsOnline(client))
            {
                return;
            }
            int userId = userCache.GetId(client);
            if (matchCache1.IsMatching(userId))
            {
                leave(client);
            }
        }

        public void OnReceive(ClientPeer client, int SubCode, object value)
        {
            switch (SubCode)
            {
                case MatchCode.ENTER_CREQ:
                    enter(client);
                    break;
                case MatchCode.LEAVE_CREQ:
                    leave(client);
                    break;
                case MatchCode.READY_CREQ:
                    ready(client);
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 进入
        /// </summary>
        private void enter(ClientPeer client)
        {
            SingleExcute.Instance.Excute(delegate ()
            {
                // 不在线
                if (!userCache.IsOnline(client))
                    return;
                int userId = userCache.GetId(client);
                // 如果用户已经在等待了
                if(matchCache1.IsMatching(userId))
                {
                    // 重复加入
                    client.Send(OpCode.MATCH, MatchCode.ENTER_SRES, -1);
                    return;
                }
                // 正常进入
                MatchRoom room = matchCache1.Enter(userId, client);
                // 给房间内所有玩家(除自己)广播, 参数:新进入玩家的ID
                UserModel model = userCache.GetModelById(userId);
                UserDto userDto = new UserDto(model.Id, model.Name, model.Been, model.WinCount, model.LoseCount, model.RunCount, model.Lv, model.Exp);
                room.Brocast(OpCode.MATCH, MatchCode.ENTER_BRO, userDto, client);
                // 返回给当前客户端,给他所有玩家的用户模型

                MatchRoomDto dto = makeRoomDto(room);
                client.Send(OpCode.MATCH, MatchCode.ENTER_SRES, dto);

                Console.WriteLine("有玩家进入房间");
            });
        }


        /// <summary>
        /// 离开
        /// </summary>
        private void leave(ClientPeer client)
        {
            SingleExcute.Instance.Excute(
                delegate ()
                { 
                    // 不在线
                    if (!userCache.IsOnline(client))
                        return;
                    int userId = userCache.GetId(client);

                    if(matchCache1.IsMatching(userId) == false)
                    {
                        // 用户没有匹配, 不能退出,非法操作
                        //client.Send(OpCode.Match, MatchCode.LEAVE_SRES, -1);
                        return;
                    }

                    // 正常离开
                    MatchRoom room = matchCache1.Leave(userId);
                    // 广播给房间内的所有人
                    room.Brocast(OpCode.MATCH, MatchCode.LEAVE_BRO, userId, client);
                    Console.WriteLine("有玩家离开房间");
                });
        }

        /// <summary>
        /// 准备
        /// </summary>
        private void ready(ClientPeer client)
        {
            SingleExcute.Instance.Excute(()=>
            {
                // 安全判断很重要!!
                if(userCache.IsOnline(client) == false)
                {
                    return;
                }
                int userId = userCache.GetId(client);
                if(matchCache1.IsMatching(userId) == false)
                {
                    return;
                }
                MatchRoom room = matchCache1.GetRoom(userId);
                // 加一个判断
                if(room.ReadyUIdList.Contains(userId) == false)
                {
                    room.Ready(userId);
                }
                room.Brocast(OpCode.MATCH, MatchCode.READY_BRO, userId);

                // 检测是否所有玩家都准备了
                if(room.IsAllReady())
                {
                    // 开始战斗
                    startFight(room.GetIdList());
                    // 通知房间内的玩家,要开始战斗了
                    room.Brocast(OpCode.MATCH, MatchCode.START_BRO, null);
                    // 销毁房间
                    matchCache1.Destory(room);
                }
            });
        }

        private MatchRoomDto makeRoomDto(MatchRoom room)
        {
            MatchRoomDto dto = new MatchRoomDto();
            foreach (var uid in room.UIdClientDict.Keys)
            {
                // 不在线
                if (!userCache.IsOnline(uid))
                    continue;

                UserModel model = userCache.GetModelById(uid);
                UserDto userDto = new UserDto(model.Id, model.Name, model.Been, model.WinCount, model.LoseCount, model.RunCount, model.Lv, model.Exp);

                dto.UIdUserDict.Add(uid, userDto);

                dto.UIdList.Add(uid);
            }
            dto.ReadyUIdList = room.ReadyUIdList;
            return dto;
        }
    }
}
